#ifndef TRANSFORMERCONTENTTRACERTTARGET_HPP_3
#define TRANSFORMERCONTENTTRACERTTARGET_HPP_3

#include "logger.hpp"
#include "transContentDefine.h"
#include "transContentErrorCode.h"
#include "transContentAssistent.hpp"
#include "transContentDispatcher.hpp"
#include "transContentIRemove.hpp"
#include "transContentThreadPool.hpp"

class TransContentFuncCallTracertTarget : public transContentIDispResponse, public transContentIRemove{
	private:
		int timeout;
		int localPort;
		int tracertFlag;
		int pathNodeCount;
		int canBeRemoved;
		int result;
		NodeAddr target;
		pthread_cond_t finishedCondtion;
		pthread_mutex_t waitMutex;
		NodeAddr* pathNodes;
		tarcertTargetCallback callback;

	public:
		TransContentFuncCallTracertTarget():timeout(INT_MAX), localPort(0), tracertFlag(TRACERT_FLAG_SINGLE), pathNodeCount(0), canBeRemoved(0), result(0), finishedCondtion(PTHREAD_COND_INITIALIZER), waitMutex(PTHREAD_MUTEX_INITIALIZER), callback(NULL){debug_enter();}
		virtual ~TransContentFuncCallTracertTarget(){
			debug_enter();
			if(pathNodes != NULL){
				logd_info("free the pathNode buffer");
				free(pathNodes);
			}
			debug_leave();
		}

		void setTimeout(int timeout){
			this->timeout = timeout;
		}

		int canRemoved() const{
			return canBeRemoved;
		}

		int getTimeout() const {
			return this->timeout;
		}

		void setLocalPort(int port){
			this->localPort = port;
		}

		int getLocalPort() const {
			return this->localPort;
		}

		void setTracertFlag(int flag){
			this->tracertFlag = flag;
		}
		int getTracertFlag() const{
			return this->tracertFlag;
		}

		void setTracertTarget(const NodeAddr* target){
			this->target = *target;
		}
		NodeAddr getTracertTarget() const {
			return this->target;
		}

		void setTracertTargetCallback(tarcertTargetCallback ttcb){
			this->callback = ttcb;
		}

		tarcertTargetCallback getTracertTargetCallback() const {
			return this->callback;
		}

		int tracertTarget(NodeAddr* nodeList, int nodeCount);

		int response(char* conent, int index);

	private:
		static void* finishedRoute(void* p){
			debug_enter();
			((TransContentFuncCallTracertTarget*)p)->finishCallback();
		}

		void finishCallback(){
			callback(result, pathNodes, pathNodeCount);
			canBeRemoved = 1;
		}

		/// no use copy constructor or assigment
		TransContentFuncCallTracertTarget(const TransContentFuncCallTracertTarget&);
		TransContentFuncCallTracertTarget operator=(const TransContentFuncCallTracertTarget&);
};
#endif //TRANSFORMERCONTENTTRACERTTARGET_HPP_3
